from django.views.generic import ListView,View
from django.shortcuts import render,redirect,get_object_or_404,HttpResponseRedirect
from django.contrib import messages  # 用于添加操作提示信息
from base import models as baseModels
from django.core.files import File
from django.conf import settings

import json,os,shutil
from django.contrib.auth.mixins import LoginRequiredMixin
from base import views_base
def get_detail_data(request):
    '''只有主窗口，获取报表数据'''
    detail_data = []
    report_code = request.POST.get('report_code')

    if report_code=='base.BaseModel':
        detail_data=views_base.WlView.get_detail_data(request)
    elif report_code=='base.SupplierModel':
        detail_data=views_base.SuppliersView.get_detail_data(request)
    return detail_data
def get_master_data(request):
    # 获取参数
    parms = {}
    for name, value in request.POST.items():
        if name in ['csrfmiddlewaretoken', ]:
            continue
        parms[name] = value
        # 可以根据实际需求添加主表数据
    return  {"user_id": request.user.id, "username": request.user.get_username(), **parms}
def get_context(request):
    report = request.POST.get('report_style')
    report_type = request.POST.get('report_type')
    detail_data = []
    if report_type=='1': #1是报表，0是子报表
        detail_data=get_detail_data(request)

    parms_data=get_master_data(request)

    # 构造完整数据
    data = {
        "Detail": detail_data,
        "Master":parms_data

    }
    context = {
        'report': report,
        'data_json': json.dumps(data, ensure_ascii=False),  # 序列化并保留中文
        'report_name': report.split('/')[-1]
    }
    return context
def create_report_from_local_file(user_id, model_code, local_file_path,type):
    """
    从本地文件创建ReportFileModel
    :param user_id: 关联的用户ID
    :param model_code: 报表标识（如"base_standardmodel"）
    :param local_file_path: 本地文件绝对路径（如"F:/default_reports/standard.pdf"）
    """
    # 1. 验证本地文件是否存在
    if not os.path.exists(local_file_path):
        raise FileNotFoundError(f"本地文件不存在：{local_file_path}")

    # filename=os.path.basename(local_file_path)

    # 3. 打开本地文件，包装为Django File对象
    # 注意：用with语句确保文件句柄关闭
    with open(local_file_path, "rb") as f:
        # File对象需要2个参数：文件句柄、文件名
        django_file = File(f, name=os.path.basename(local_file_path))

        # 4. 创建ReportFileModel实例
        report = baseModels.ReportFileModel.objects.create(
            user_id=user_id,
            code=model_code,
            type=type,
            state="1",
            default=True,
            report_file=django_file,  # 传递Django File对象
            report_name=os.path.basename(local_file_path)
        )
    report.report_name=os.path.basename(report.report_file.path)
    report.save()
    # print(f"从本地文件创建报表成功：ID={report.id}，文件路径：{report.report_file.path}")
    return report.report_file.name,report.report_name
def creatNewFile(old_file,new_file_name):
    # 2. 验证原始文件是否存在（避免复制不存在的文件）
    if not os.path.exists(old_file):
        raise FileNotFoundError(f"原始文件不存在：{old_file}")
    # dirname = os.path.dirname(old_file)  # 原始文件所在目录
    filename, ext = os.path.splitext(os.path.basename(old_file))  # 文件名+扩展名拆分

    # 新文件名：原文件名 + "_copy" + 扩展名（如 "test_copy.pdf"）
    new_filename = f"{new_file_name}{ext}"
    # 新文件的绝对路径（与原始文件同目录）
    # new_file = os.path.join(dirname, new_filename)
    new_file=os.path.join(settings.MEDIA_ROOT,'temp',new_filename)
    # 4. 避免新文件已存在（可选：若存在则加数字后缀，如 test_copy_1.pdf）
    count = 1
    while os.path.exists(new_file):
        new_filename = f"{new_file_name}_copy_{count}{ext}"
        # new_file = os.path.join(dirname, new_filename)
        new_file=os.path.join(settings.MEDIA_ROOT,'temp',new_filename)
        count += 1

    # 5. 执行复制（用copy2保留文件元数据：修改时间、权限等）
    try:
        shutil.copy2(old_file, new_file)  # 复制文件
        # print(f"文件复制成功！\n原始文件：{old_file}\n新文件：{new_file}")
        return new_file
    except Exception as e:
        return 'cuowu'

class PrintView(LoginRequiredMixin,View):
    """物料添加视图：处理原料、添加剂、包装材料的添加逻辑"""
    template_name ='report/ReportHome.htm'  # 模板路径集中管理

    def creatreport(self,request):
        report = request.POST.get('report_style') #原来的报名名称
        user_id = request.user.id
        model = request.POST.get('report_code')
        type = request.POST.get('report_type')
        report_name = request.POST.get('report_name')
        if report:
            old_file = os.path.join(settings.MEDIA_ROOT, report)
        else:
            if type == '1':
                url = f"uploads/files/report/0/{model}/simple.grf"
            else:
                url = f"uploads/files/report/0/{model}/children/simple.grf"
            if not os.path.exists(os.path.join(settings.MEDIA_ROOT, url)):
                url = f"uploads/files/report/0/simple.grf"
            old_file = os.path.join(settings.MEDIA_ROOT, url)
        if report_name:
            old_file = creatNewFile(old_file, new_file_name=report_name)
        report_url, report_name = create_report_from_local_file(user_id=user_id, model_code=model,
                                                                local_file_path=old_file, type=type)

        # context = {
        #     'report': report_url,
        #     'report_name': report_name
        #
        # }

        # 重定向回原页面
        return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
    def altReportName(self,request):
        # 获取表单提交的参数
        report_style = request.POST.get('report_style')  # 原报表文件名（带路径）
        new_report_name = request.POST.get('report_name', '').strip()
        model = 'base.BaseModel'
        report_type = '1'
        user_id = request.user.id

        # 校验必要参数
        if not all([report_style, new_report_name, model, report_type]):
            messages.error(request, "缺少必要参数，请重试")
            return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
        if '.' in new_report_name:
            messages.error(request, "新名字有非法字符，不要加后缀名，请重试")
            return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
        # 查询对应的报表记录
        try:
            report_file = baseModels.ReportFileModel.objects.get(
                user_id=user_id,
                report_file=report_style  # 匹配原文件路径
            )
        except baseModels.ReportFileModel.DoesNotExist:
            messages.error(request, "未找到对应的报表记录")
            return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))

        # 处理文件重命名
        # 1. 获取原文件完整路径和扩展名
        old_file_path = os.path.join(settings.MEDIA_ROOT, report_style)
        file_ext = os.path.splitext(report_style)[1]  # 获取扩展名（如 .docx）

        # 2. 构建新文件名（保留扩展名）
        # 确保新文件名不包含路径分隔符，避免安全问题
        new_filename = f"{new_report_name}{file_ext}".replace('/', '').replace('\\', '')

        # 3. 构建新文件完整路径（保持原目录结构）
        old_file_dir = os.path.dirname(old_file_path)
        new_file_path = os.path.join(old_file_dir, new_filename)

        try:
            # 4. 重命名文件系统中的文件
            if os.path.exists(old_file_path):
                os.rename(old_file_path, new_file_path)
            else:
                messages.warning(request, "原文件不存在，仅更新数据库记录")

            # 5. 更新数据库记录（report_file 存储相对路径）
            # 计算新的相对路径（相对于 MEDIA_ROOT）
            new_relative_path = os.path.relpath(new_file_path, settings.MEDIA_ROOT)
            report_file.report_name = new_filename  # 存储不带扩展名的名称（或根据需求调整）
            report_file.report_file = new_relative_path.replace('\\', '/')  # 更新 FileField 路径
            report_file.save()

            messages.success(request, f"报表名称已更新为：{new_report_name}")

        except Exception as e:
            messages.error(request, f"修改失败：{str(e)}")

        # 重定向回原页面
        return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
    def post(self, request):
        """展示报表文件，修改只改get_detail_data()"""
        print_type=request.POST.get('print_type')


        if print_type=='preview':
            context = get_context(request)
            return render(request, self.template_name,context)
        elif print_type=='print':
            context = get_context(request)
            return render(request, 'report/ReportPrintNow.htm', context)
        elif print_type=='design':
            report = request.POST.get('report_style')
            report_name = request.POST.get('report_name')
            context = {
                'report': report,
                'report_name': report_name,
            }
            return render(request, 'report/DesignReport.htm', context)
        elif print_type == 'creatReport':
            return self.creatreport(request)
        elif print_type == 'altReportName':
            return self.altReportName(request)